package com.kingzoon.seckill.service.impl.capital;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import payment.tools.util.GUID;
import payment.tools.util.TimeUtil;

import com.kingzoon.seckill.dao.FmsCapFrozenMapper;
import com.kingzoon.seckill.dao.UaCapAcctInfoMapper;
import com.kingzoon.seckill.dao.UaCapChannelMapper;
import com.kingzoon.seckill.dao.UaMemberInfoMapper;
import com.kingzoon.seckill.dto.Result;
import com.kingzoon.seckill.entity.FmsCapFrozen;
import com.kingzoon.seckill.entity.UaCapAcctInfo;
import com.kingzoon.seckill.entity.UaCapAcctInfoKey;
import com.kingzoon.seckill.entity.UaCapChannel;
import com.kingzoon.seckill.entity.UaCapChannelExample;
import com.kingzoon.seckill.entity.UaMemberInfo;
import com.kingzoon.seckill.entity.UaMemberInfoExample;
import com.kingzoon.seckill.enums.MacroDefine;
import com.kingzoon.seckill.service.WithdrawCashApplyService;
import com.kingzoon.seckill.util.UtilTools;

@Service
public class WithdrawCashApplyServiceImpl implements WithdrawCashApplyService {
	
	private HashMap<String,Object> paramMap = new HashMap<String,Object>();
	
	@Autowired
	private UaMemberInfoMapper uaMemberInfoDao;
	
	@Autowired
	private UaCapAcctInfoMapper uaCapAcctInfoDao;
	
	@Autowired
	private UaCapChannelMapper uaCapChannelDao;
	
	@Autowired
	private FmsCapFrozenMapper fmsCapFrozenDao;
	
	private UaMemberInfoExample uaMemberInfoExample = new UaMemberInfoExample();
	private UaMemberInfo uaMemberInfo = new UaMemberInfo();
	private UaCapChannelExample uaCapChannelExample = new UaCapChannelExample();
	private UaCapChannel uaCapChannel = new UaCapChannel();
	private UaCapAcctInfoKey uaCapAcctInfoKey = new UaCapAcctInfoKey();
	private UaCapAcctInfo uaCapAcctInfo = new UaCapAcctInfo();
	private FmsCapFrozen fmsCapFrozen = new FmsCapFrozen();

	public Result<HashMap<String, Object>> doBusiness(HashMap<String, Object> mapParam, Result<HashMap<String, Object>> rs) {
		paramMap = mapParam;
		if(preCheck(rs)){
			if(cache(rs)){
				if(check(rs)){
					if(before(rs)){
						if(clear(rs)){
							after(rs);
						}
					}
				}
			}
		}
		return rs;
	}

	public boolean preCheck(Result<HashMap<String, Object>> rs) {
		String[] keys = {"exchangeId","distributorId","memberId","smsCode","amount","channelType"};
		String emptyString = UtilTools.isParamEmpty(keys, paramMap);
		if(!UtilTools.isEmpty(emptyString)){
			rs.setFlag(false);
			rs.setCode(MacroDefine.GS_CODE.E_1002.getCode());
			rs.setMessage(MacroDefine.GS_CODE.E_1002.getMessage());
			return false;
		}
		return true;
	}

	public boolean cache(Result<HashMap<String, Object>> rs) {
		return true;
	}

	public boolean check(Result<HashMap<String, Object>> rs) {
		//校验会员信息表
		uaMemberInfoExample.createCriteria().andMemberIdEqualTo(UtilTools.valueOf(paramMap.get("memberId")));
		List<UaMemberInfo> memberInfoList = uaMemberInfoDao.selectByExample(uaMemberInfoExample);
		if(memberInfoList == null || memberInfoList.size() <= 0){
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5400.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5400.getMessage());
			return false;
		}
		uaMemberInfo = memberInfoList.get(0);
		
		
		//校验资金账户渠道关系表
		uaCapChannelExample.createCriteria().andMemberIdEqualTo(UtilTools.valueOf(paramMap.get("memberId")))
		.andChannelTypeEqualTo(UtilTools.valueOf(paramMap.get("channelType")));
		List<UaCapChannel> capChannelList = uaCapChannelDao.selectByExample(uaCapChannelExample);
		if(capChannelList == null || capChannelList.size() <= 0){
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5400.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5400.getMessage());
			return false;
		}
		uaCapChannel = capChannelList.get(0);
		
		//校验资金账户信息表
		uaCapAcctInfoKey.setExchangeId((String)paramMap.get("exchangeId"));
		uaCapAcctInfoKey.setDistributorId((String)paramMap.get("distributorId"));
		uaCapAcctInfoKey.setMemberId(uaCapChannel.getMemberId());
		uaCapAcctInfoKey.setCapitalAccount(uaCapChannel.getCapitalAccount());
		uaCapAcctInfo = uaCapAcctInfoDao.selectByPrimaryKey(uaCapAcctInfoKey);
		if("1".equals(uaCapAcctInfo.getAccountStatus()) || "2".equals(uaCapAcctInfo.getAccountStatus())){//1-冻结，2-销户
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5400.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5400.getMessage());
			return false;
		}
		int a = uaCapAcctInfo.getCurBalance().compareTo(new BigDecimal(0));
		if(a != 1){//当前余额大于0
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5411.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5411.getMessage());
			return false;
		}
		int b = uaCapAcctInfo.getAvailableBalance().compareTo(new BigDecimal(UtilTools.valueOf(paramMap.get("amount"))));
		if(b == -1){//可用余额大于等于提现申请金额
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5411.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5411.getMessage());
			return false;
		}
		int c = uaCapAcctInfo.getCurAvailableWithdraw().compareTo(new BigDecimal(UtilTools.valueOf(paramMap.get("amount"))));
		if(c == -1){//当前可取余额大于等于提现申请金额
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5411.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5411.getMessage());
			return false;
		}
		return true;
	}

	public boolean before(Result<HashMap<String, Object>> rs) {
		String businessCode = "106";//106-资金冻结
		String businessName = "frozen";
		paramMap.put("exchangeId", uaMemberInfo.getExchangeId());
		paramMap.put("distributorId", uaMemberInfo.getDistributorId());
		paramMap.put("memberId", uaMemberInfo.getMemberId());
		paramMap.put("fronzenSerialno", GUID.getTxNo());
		paramMap.put("capitalAccount", uaCapAcctInfo.getCapitalAccount());
		paramMap.put("channelType", uaCapAcctInfo.getChannelType());
		paramMap.put("applyAmount", new BigDecimal((String)paramMap.get("amount")));
		paramMap.put("businessCode", businessCode);
		paramMap.put("businessName", businessName);
		paramMap.put("beforeBalance", uaCapAcctInfo.getCurBalance());
		paramMap.put("afterBalance", uaCapAcctInfo.getCurBalance());
		paramMap.put("insertDate", TimeUtil.getTimeStamp().substring(0, 8));
		paramMap.put("insertTime", TimeUtil.getTimeStamp().substring(8));
		fmsCapFrozen.setExchangeId(UtilTools.valueOf(paramMap.get("exchangeId")));
		fmsCapFrozen.setDistributorId(UtilTools.valueOf(paramMap.get("distributorId")));
		fmsCapFrozen.setMemberId(UtilTools.valueOf(paramMap.get("memberId")));
		fmsCapFrozen.setFronzenSerialno(UtilTools.valueOf(paramMap.get("fronzenSerialno")));
		fmsCapFrozen.setCapitalAccount(UtilTools.valueOf(paramMap.get("capitalAccount")));
		fmsCapFrozen.setChannelType(UtilTools.valueOf(paramMap.get("channelType")));
		fmsCapFrozen.setApplyAmount((BigDecimal)paramMap.get("applyAmount"));
		fmsCapFrozen.setBusinessCode(UtilTools.valueOf(paramMap.get("businessCode")));
		fmsCapFrozen.setBusinessName(UtilTools.valueOf(paramMap.get("businessName")));
		fmsCapFrozen.setBeforeBalance((BigDecimal)paramMap.get("beforeBalance"));
		fmsCapFrozen.setAfterBalance((BigDecimal)paramMap.get("afterBalance"));
		fmsCapFrozen.setInsertDate(UtilTools.valueOf(paramMap.get("insertDate")));
		fmsCapFrozen.setInsertTime(UtilTools.valueOf(paramMap.get("insertTime")));
		return true;
	}

	public boolean clear(Result<HashMap<String, Object>> rs) {
		//TODO 单笔代付
		HashMap<String,Object> reqMap = new HashMap<String, Object>();
		reqMap.put("bankNo", paramMap.get("bankNo"));
		reqMap.put("bankAcc", paramMap.get("bankAcc"));
		reqMap.put("amount", paramMap.get("amount"));
		boolean flag = orderClear(reqMap);
		if(!flag){
			rs.setFlag(false);
			rs.setCode(MacroDefine.ZH_CODE.E_5410.getCode());
			rs.setMessage(MacroDefine.ZH_CODE.E_5410.getMessage());
			return false;
		}
		
		//更新资金余额表
		uaCapAcctInfo.setAvailableBalance(uaCapAcctInfo.getAvailableBalance().subtract(new BigDecimal(UtilTools.valueOf(paramMap.get("amount")))));
		uaCapAcctInfo.setCurAvailableWithdraw(uaCapAcctInfo.getAvailableBalance());
		uaCapAcctInfo.setCurWithdrawFrozen(uaCapAcctInfo.getCurWithdrawFrozen().add(new BigDecimal(UtilTools.valueOf(paramMap.get("amount")))));
		uaCapAcctInfo.setUpdateDate(Long.valueOf(TimeUtil.getTimeStamp().substring(0, 8)));
		uaCapAcctInfo.setUpdateTime(Long.valueOf(TimeUtil.getTimeStamp().substring(8)));
		int a = uaCapAcctInfoDao.updateByPrimaryKeySelective(uaCapAcctInfo);
		if(a != 1){
			rs.setFlag(false);
			rs.setCode(MacroDefine.JC_CODE.R_9999.getCode());
			rs.setMessage(MacroDefine.JC_CODE.R_9999.getMessage());
			return false;
		}
		//写入资金冻结流水表
		fmsCapFrozen.setConfirmAmount(fmsCapFrozen.getApplyAmount());
		fmsCapFrozen.setConfirmSerialno(fmsCapFrozen.getFronzenSerialno());
		fmsCapFrozen.setTradeDate(fmsCapFrozen.getInsertDate());
		fmsCapFrozen.setTradeTime(fmsCapFrozen.getInsertTime());
		int b = fmsCapFrozenDao.insertSelective(fmsCapFrozen);
		if(b != 1){
			rs.setFlag(false);
			rs.setCode(MacroDefine.JC_CODE.R_9999.getCode());
			rs.setMessage(MacroDefine.JC_CODE.R_9999.getMessage());
			return false;
		}
		return true;
	}

	public boolean after(Result<HashMap<String, Object>> rs) {
		HashMap<String, Object> respMap = new HashMap<String,Object>();
		respMap.put("exchangeId", uaCapAcctInfo.getExchangeId());
		respMap.put("distributorId", uaCapAcctInfo.getDistributorId());
		respMap.put("memberId", uaCapAcctInfo.getMemberId());
		respMap.put("capitalAccount", uaCapAcctInfo.getCapitalAccount());
		respMap.put("curBalance", uaCapAcctInfo.getCurBalance());
		respMap.put("availableBalance", uaCapAcctInfo.getAvailableBalance());
		respMap.put("curAvailableBalance", uaCapAcctInfo.getCurAvailableWithdraw());
		respMap.put("currencyType", uaCapAcctInfo.getCurrencyType());
		rs.setData(respMap);
		rs.setFlag(true);
		rs.setCode(MacroDefine.JC_CODE.S_0000.getCode());
		rs.setMessage(MacroDefine.JC_CODE.S_0000.getMessage());
		return true;
	}
	
	public boolean orderClear(HashMap<String,Object> reqMap){
		//TODO 单笔代付
		return true;
	}

}
